/***************************************************************************
 *   Copyright (C) 2008 by Rysiek Kr�l,,,   *
 *   rysiek@Babylon2   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include "commentdialog.h"

#include <zlib.h>
#include <rexifdata.h>

#include <QDomDocument>
#include <QDomElement>
#include <QDir>
#include <QTextCodec>


/**
* Konstruktor Klasy
*/
CommentDialog::CommentDialog(QListWidget *listWidget, QWidget* parent, Qt::WFlags fl)
: QDialog( parent, fl ), Ui::CommentDialog()
{
	setupUi(this);
	for(int i=0; i<listWidget->count();i++){
		if (listWidget->item(i)->isSelected())
			this->selectedList.append(dynamic_cast<PictureListWidgetItem*>(listWidget->item(i)));
	}
	this->timeStampEdit->setDisplayFormat("dd.MMMM.yyyy hh:mm");
	this->setSlots();
	this->timeStampEdit->setEnabled(false);
	this->setComments();
	
}
/**
* Destruktor Klasy
*/
CommentDialog::~CommentDialog()
{
}

/**
* Łączy Sygnały ze slotami
*/
void CommentDialog::setSlots()
{
connect(this->timeActionCombo, SIGNAL (currentIndexChanged(int)), this, SLOT (comboActionChanged(int)));
}

/*$SPECIALIZATION$*/
void CommentDialog::reject()
{
  QDialog::reject();
}

/**
* Akcja po kliknięciu przycisku OK
*/
void CommentDialog::accept()
{
        bool changeNote = false;
        bool changePlace = false;
        bool changeTimeStamp = false;

        if (this->note != this->noteEdit->toPlainText()) changeNote = true;
        if (this->place != this->placeEdit->text()) changePlace = true;
        if (this->timeStamp != this->timeStampEdit->dateTime()&&this->timeActionCombo->currentIndex()!=0) changeTimeStamp = true;
        if (!changeNote && !changePlace && !changeTimeStamp) {
                       this->done(1);
        } else {
                this->buildCommentString(changeNote,changePlace,changeTimeStamp);
        }
}

/**
* Ustawia odpowiednie dane komentarza w konkretnych polach
*/
void CommentDialog::setComments()
{
        this->note = this->selectedList.at(0)->getNote();
        this->place = this->selectedList.at(0)->getPlace();
        this->timeStamp = this->selectedList.at(0)->getDateTime();
	
	RExifData *exifData = new RExifData(this->selectedList.at(0)->getFile().absoluteFilePath().toLatin1().data());
	if (!exifData->isExif()) {
		this->timeActionCombo->removeItem(3);
	}
       if (this->selectedList.size()>1)
                for (int i=1;i<this->selectedList.size();i++) {
			if (this->note != this->selectedList.at(i)->getNote()) this->note = "";
			if (this->place != this->selectedList.at(i)->getPlace()) this->place = "";
			if (this->timeStamp != this->selectedList.at(i)->getDateTime()) this->timeStamp = QDateTime::fromTime_t(0);
                }
        this->noteEdit->setPlainText(this->note);
        this->placeEdit->setText(this->place);
        this->timeStampEdit->setDateTime(this->timeStamp);
        delete exifData;
}

/**
* Buduje QString do zapisania w pliku z komentarzem i wywołuje metode zapisującą
*/
void CommentDialog::buildCommentString(bool changeNote, bool changePlace, bool changeTimeStamp)
{
        QDomDocument doc;

        for (int i=0; i<this->selectedList.size(); i++) {
                if (this->selectedList.at(i)->getCommentString().isEmpty() ) {
                        doc = this->buildNewComment();
                } else {
                        doc.setContent(this->selectedList.at(i)->getCommentString());
                }
                if (changeNote) {
                        QDomElement rootElement = doc.firstChildElement("Comment");
                        QDomElement oldElement = rootElement.firstChildElement("Note");
                        QDomElement newElement = doc.createElement("Note");
                        QDomText t = doc.createTextNode(this->noteEdit->toPlainText());
                        newElement.appendChild(t);
                        rootElement.replaceChild(newElement, oldElement);
                }
                if (changePlace) {
                        QDomElement rootElement = doc.firstChildElement("Comment");
                        QDomElement oldElement = rootElement.firstChildElement("Place");
                        QDomElement newElement = doc.createElement("Place");
                        QDomText t = doc.createTextNode(this->placeEdit->text());
                        newElement.appendChild(t);
                        rootElement.replaceChild(newElement, oldElement);
                }
                if (changeTimeStamp) {
                        QDomElement rootElement = doc.firstChildElement("Comment");
                        QDomElement oldElement = rootElement.firstChildElement("Time");
                        QDomElement newElement = doc.createElement("Time");
                        QDomText t;
                        if (this->timeActionCombo->currentIndex()==3) {
                                RExifData *exifData = new RExifData(this->selectedList.at(i)->getFile().absoluteFilePath().toLatin1().data());
                                 t = doc.createTextNode(QString::number(exifData->getDate().toTime_t()));
                                 delete exifData;
                        } else {
                                if (this->timeStampEdit->dateTime().toTime_t()!=0) {
                                        int w = this->timeStampEdit->dateTime().toTime_t();
                                        t = doc.createTextNode(QString::number(w));
                                } else {
                                        t = doc.createTextNode("");
                                }
                        }
                        newElement.appendChild(t);
                        rootElement.replaceChild(newElement, oldElement);
                }
                QString commentString = this->encodeCharacters(doc.toString());


                this->writeComment(commentString ,i);
        }
}

/**
* archiwizuje i zapisuje do pliku komentarz
* @Param commentString - komentarz
* @param itemIndex - numer indexu pliku w thia->selectedList
*/
void CommentDialog::writeComment(QString commentString, int itemIndex)
{
	QFileInfo fileInfo = this->selectedList.at(itemIndex)->getFile();
	QDir dir = fileInfo.dir();
	if (!dir.exists(".comments")) dir.mkdir(".comments");
	dir.cd(".comments");
	QString fileName = fileInfo.fileName();
	fileName = fileName + ".xml";
	fileName = dir.filePath(fileName);
	char buf[commentString.size()];
	QByteArray array = commentString.toLocal8Bit();
	char* buffer = array.data();
	for (int i=0; i < commentString.size();i++){ 
		buf[i] = *buffer++;	
	}
	gzFile pliczek;
	const char *filePath;
	array = fileName.toLocal8Bit();
	filePath = array.data();
	pliczek = gzopen ( filePath, "wb" );
	gzwrite(pliczek, buf, sizeof(buf));
	gzclose(pliczek);
        this->done(1);
}

/**
* Zakodowywuje polskie znaczki (bez tej funkcji gThumb nie potrafi odczytac komentarza z Polskimi znakami)
* @param string - string do zdekodowania
* @return QString - zdekodowany QString
*/
QString CommentDialog::encodeCharacters(QString string)
{
	string.replace("ó", "&#xF3;");
	string.replace("ł", "&#x142;");
	string.replace("Ś", "&#x15A;");
	string.replace("ś", "&#x15B;");
	string.replace("ż", "&#x17C;");
	string.replace("ę", "&#x119;");
	string.replace("ń", "&#x144;");	
	return string;
}

/**
* Zarządza zachowaniem this->timeStampEdit w przypadku zmiany opcji w thia->timeActionCombo
* @param action - numer indexu na który zmienia się akcja
*/
void CommentDialog::comboActionChanged(int action)
{
        switch (action) {
        case(0):
                this->timeStampEdit->setEnabled(false);
                this->timeStampEdit->setDateTime(this->timeStamp);
                break;
        case(1): 
                this->timeStampEdit->setEnabled(true);
                break;
        case(2):
        	this->timeStampEdit->setEnabled(false);
                this->timeStampEdit->setDateTime(QDateTime::currentDateTime());
        break;
        case(3):
                this->timeStampEdit->setEnabled(false);
               	RExifData *exifData = new RExifData(this->selectedList.at(0)->getFile().absoluteFilePath().toLatin1().data());
		if (exifData->isExif()) {
			this->timeStampEdit->setDateTime(exifData->getDate());
		}
		delete exifData;
                break;
        }
}

/**
* Builds new comment XML document. In Future there have to be XML classes
*/
QDomDocument CommentDialog::buildNewComment()
{
        QDomDocument doc("");

        /*   QDomElement root = doc.createElement("Comment");
           root.setAttribute("format", "2.0");
           doc.appendChild(root);

           QDomElement element = doc.createElement("Note");
           root.appendChild(element);
           element = doc.createElement("Place");
           root.appendChild(element);
           element = doc.createElement("Time");
           root.appendChild(element);
           element = doc.createElement("Keywords");
           root.appendChild(element);
        QDomText
        */
        QString docString = "<?xml version=\"1.0\"?>\n<Comment format=\"2.0\"><Place></Place><Time></Time><Note/><Keywords></Keywords></Comment>";
        doc.setContent(docString);
        return doc;

}

